﻿<# 
.SYNOPSIS 
    Invokes the UBBGen command.
.DESCRIPTION 
    The command Invoke-UBBGen is used to re-crete the UBB file from an existing UBX and CFG file.
    Register-PsftConfiguration or Register-PsftPrcsSchedulerConfiguration must be executed after running Invoke-UBBGen.
    It is advised that the configuration be re-registered immediately after running this command, otherwise the server
    may not behave as expected.
.NOTES 
    File Name  : Invoke-UBBGen.ps1 
    Author     : Scott Kearney - scott@kearney.tk 
    Requires   : PowerShell V3 
.EXAMPLE 
    Invoke-UBBGen -PS_HOME $PS_HOME -PS_CFG_HOME $PS_CFG_HOME -ServerType "AppServer" -Domain "DOMAIN1"
    Invokes UBBGen to crete a new UBB file for the Application Server domain DOMAIN1.
.EXAMPLE 
    $features = Get-PsftFeature -PS_HOME $PS_HOME -PS_CFG_HOME $PS_CFG_HOME -ServerType $ServerType -Domain "DOMAIN1"
    $features.JOLT = $true
    Invoke-UBBGen -PS_HOME $PS_HOME -PS_CFG_HOME $PS_CFG_HOME -ServerType "AppServer" -Domain "DOMAIN1" -UBXSettingsObject $features
    Invokes UBBGen to crete a new UBB file for the Application Server domain DOMAIN1, ensuring that the JOLT feature will be enabled.
.PARAMETER PS_HOME
    The full path to the PS_HOME directory for this domain.
.PARAMETER PS_CFG_HOME
    The full path to the PS_CFG_HOME directory for this domain.
.PARAMETER ServerType
    The type of server to act on.
    One of AppServer or PrcsScheduler.
.PARAMETER Domain
    The name of the domain on which to perform the action.
.PARAMETER UBXSettingsObject
    An Object containing a list of properties and boolean values
    for each of the available features in the UBX file.
#> 
function Invoke-UBBGen
{
    [CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact='High')]
    Param
    (
        # The full path to the PS_HOME directory for this domain.
        # See http://docs.oracle.com/cd/E41633_01/pt853pbh1/eng/pt/tsvt/concept_UnderstandingPS_HOMEandPS_CFG_HOME-eb7ece.html
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   HelpMessage = "The full path to the PS_HOME directory for this domain.",
                   Position=0)]
        [ValidateScript({Validate_PS_HOME $_})]
        [String]
        $PS_HOME,

        # The full path to the PS_CFG_HOME directory for this domain.
        # See http://docs.oracle.com/cd/E41633_01/pt853pbh1/eng/pt/tsvt/concept_UnderstandingPS_HOMEandPS_CFG_HOME-eb7ece.html
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   HelpMessage = "The full path to the PS_CFG_HOME directory for this domain.",
                   Position=1)]
        [ValidateScript({Validate_PS_CFG_HOME $_})]
        [String]
        $PS_CFG_HOME,

        # The type of server on which to perform the action.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   HelpMessage = "The type of server on which to perform the action.",
                   Position=2)]
        [ValidateSet("AppServer","PrcsScheduler")]
        $ServerType,

        # The name of the domain on which to perform the action.
        # Should be a directory under the PS_CFG_HOME
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   HelpMessage = "The name of the domain on which to perform the action.",
                   Position=3)]
        [ValidateScript({Validate_Domain $PS_CFG_HOME $ServerType $_})]
        [String]
        $Domain,

        # A UBX Settings Object contains a list of properties and boolean values
        # for each of the available features in the UBX file.
        # The return from Get-PsftFeature can be passed here, for example.
        [Parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$true,
                   Position=4)]
        [ValidateNotNullOrEmpty()]
        [Object]
        $UBXSettingsObject
    )

    Begin
    {
    }
    Process
    {
        # Set up variables
        $command = ""

        # Set up required environment variables
        $env:PS_HOME = $PS_HOME
        $env:PS_CFG_HOME = $PS_CFG_HOME
        $env:PS_SERVDIR = "$PS_CFG_HOME\appserv\$Domain"
        $env:PS_SERVER_CFG = "$PS_CFG_HOME\appserv\$Domain\psappsrv.cfg"
        $env:UBBCONFIG = "$PS_CFG_HOME\appserv\$Domain\psappsrv.ubb"
        $env:PS_MACH = $env:COMPUTERNAME
        $env:TUXCONFIG= "$PS_CFG_HOME\appserv\$Domain\PSTUXCFG"

        # Define each of the configuration files
        # The configuration file path depends on the $ServerType selected
        switch ($ServerType)
        {
            'PrcsScheduler' {
                                $configFiles = @{
                                    "UBX" = "$PS_CFG_HOME\appserv\prcs\$Domain\psprcsrv.ubx";
                                    "CFG" = "$PS_CFG_HOME\appserv\prcs\$Domain\psprcs.cfg";
                                    "UBB" = "$PS_CFG_HOME\appserv\prcs\$Domain\psprcsrv.ubb";
                                    "VAL" = "$PS_CFG_HOME\appserv\prcs\$Domain\psprcsrv.val";
                                }
                            }
                 #AppServer
                    Default {
                                $configFiles = @{
                                    "UBX" = "$PS_CFG_HOME\appserv\$Domain\psappsrv.ubx";
                                    "CFG" = "$PS_CFG_HOME\appserv\$Domain\psappsrv.cfg";
                                    "UBB" = "$PS_CFG_HOME\appserv\$Domain\psappsrv.ubb";
                                    "VAL" = "$PS_CFG_HOME\appserv\$Domain\psappsrv.val";
                                }
                            }
        }

        <#
        $configFiles = @{
            "UBX" = "$PS_CFG_HOME\appserv$(if($ServerType -eq "PrcsScheduler"){"\prcs"})\$Domain\$(if($ServerType -eq "PrcsScheduler"){"psprcsrv"}else{"psappsrv"}).ubx";
            "CFG" = "$PS_CFG_HOME\appserv$(if($ServerType -eq "PrcsScheduler"){"\prcs"})\$Domain\$(if($ServerType -eq "PrcsScheduler"){"psprcs"  }else{"psappsrv"}).cfg";
            "UBB" = "$PS_CFG_HOME\appserv$(if($ServerType -eq "PrcsScheduler"){"\prcs"})\$Domain\$(if($ServerType -eq "PrcsScheduler"){"psprcsrv"}else{"psappsrv"}).ubb";
            "VAL" = "$PS_CFG_HOME\appserv$(if($ServerType -eq "PrcsScheduler"){"\prcs"})\$Domain\$(if($ServerType -eq "PrcsScheduler"){"psprcsrv"}else{"psappsrv"}).val";
        }
        #>
        
        # Certain values must be passed to the ubbgen.exe command.
        # These values are already present in the CFG file. (DBName, DBType, UserId, etc...)
        # We read the values from this file and use them to pass to the ubbgen.exe program.
        $pscfg = Get-PsftConfiguration -PS_HOME $PS_HOME -PS_CFG_HOME $PS_CFG_HOME -ServerType $ServerType -Domain $Domain

        # Now we build the arguments which will be passed to ubbgen.exe
        
        # -t <ubx_file> -c <cfg_file> -o <ubb_file> -v <val_file> -q(uiet) y/n
        $command = "-t ""$($configFiles.UBX)"" -c ""$($configFiles.CFG)"" -o ""$($configFiles.UBB)"" -v ""$($configFiles.VAL)"" -q y "
        
        switch ($ServerType)
        {
            'AppServer'     
            {
                # -s "DBNAME/DBTYPE/OPRID/OPRPSWD/TESTSERV/ADD_TO_PATH/CONNECT_ID/CONNECT_PSWD/SERV_NAME/DomainConnectionPswd/(NO)ENCRYPT"
                $command += "-s ""$($pscfg.Startup.DBName)/$($pscfg.Startup.DBType)/$($pscfg.Startup.UserId)/$($pscfg.Startup.UserPswd -replace "/","\")/$($pscfg.'Domain Settings'.'Domain Id')/$(if($pscfg.'Domain Settings'.'Add to PATH'){$pscfg.'Domain Settings'.'Add to PATH'}else{"_____"})/$($pscfg.Startup.ConnectId)/$($pscfg.Startup.ConnectPswd -replace "/","\")/$(if($pscfg.Startup.ServerName){$pscfg.Startup.ServerName}else{"_____"})/$(if($pscfg.Security.DomainConnectionPwd){$pscfg.Security.DomainConnectionPwd}else{"_____"})"" "
        
                # -p WSL_PORT/JOLT_PORT/JRAD_PORT
                $command += "-p $($pscfg.'Workstation Listener'.Port)/$($pscfg.'JOLT Listener'.Port)/$($pscfg.'JOLT Relay Adapter'.'Listener Port') "
            }
            'PrcsScheduler' 
            {
                # -ps "DBNAME/DBTYPE/PrcsServer/UserId/UserPswd/ConnectId/ConnectPswd/ServerName/LogOutputDir/SQRBin/ADD_TO_PATH/DBBin/CrystalPath/DomainConnectionPswd/(NO)ENCRYPT"
                $command += "-ps """+
                            "$(SanitizeInput $pscfg.Startup.DBName)/"+
                            "$(SanitizeInput $pscfg.Startup.DBType)/"+
                            "$(SanitizeInput $pscfg.'Process Scheduler'.'PrcsServerName')/"+
                            "$(SanitizeInput $pscfg.Startup.UserId)/"+
                            "$(SanitizeInput $pscfg.Startup.UserPswd)/"+
                            "$(SanitizeInput $pscfg.Startup.ConnectId)/"+
                            "$(SanitizeInput $pscfg.Startup.ConnectPswd -replace "/","\")/"+
                            "$(SanitizeInput $pscfg.Startup.ServerName)/"+
                            "$(SanitizeInput $pscfg.'Process Scheduler'.'Log/Output Directory')/"+
                            "$(SanitizeInput $pscfg.'SQR'.'SQRBIN')/"+
                            "$(SanitizeInput $pscfg.'Domain Settings'.'Add to PATH')/"+
                            "$(SanitizeInput $pscfg.'Process Scheduler'.'DBBIN')/"+
                            "$(SanitizeInput $pscfg.'Crystal'.'CrystalEXEPath')/"+
                            "$(SanitizeInput $pscfg.Security.DomainConnectionPwd)"" "
            }
        }
        
        
        # The -u parameter is not required.
        # If the settings were specified in the arguments, then use them.
        # Otherwise, we can run the command without them.
        if($UBXSettingsObject){
        switch ($ServerType)
        {
            'AppServer' 
            {
                $command += "-u " +
                        "`{PUBSUB`}=$(if($UBXSettingsObject.PUBSUB){"Yes"}else{"No"})/" +
                        "`{QUICKSRV`}=$(if($UBXSettingsObject.QUICKSRV){"Yes"}else{"No"})/" +
                        "`{QUERYSRV`}=$(if($UBXSettingsObject.QUERYSRV){"Yes"}else{"No"})/" +
                        "`{JOLT`}=$(if($UBXSettingsObject.JOLT){"Yes"}else{"No"})/" +
                        "`{JRAD`}=$(if($UBXSettingsObject.JRAD){"Yes"}else{"No"})/" +
                        "`{WSL`}=$(if($UBXSettingsObject.WSL){"Yes"}else{"No"})/" +
                        "`{DBGSRV`}=$(if($UBXSettingsObject.DBGSRV){"Yes"}else{"No"})/" +
                        "`{RENSRV`}=$(if($UBXSettingsObject.RENSRV){"Yes"}else{"No"})/" +
                        "`{MCF`}=$(if($UBXSettingsObject.MCF){"Yes"}else{"No"})/" +
                        "`{PPM`}=$(if($UBXSettingsObject.PPM){"Yes"}else{"No"})/" +
                        "`{ANALYTICSRV`}=$(if($UBXSettingsObject.ANALYTICSRV){"Yes"}else{"No"})/" +
                        "`{DOMAIN_GW`}=$(if($UBXSettingsObject.DOMAIN_GW){"Yes"}else{"No"})/" +
                        "`{VERITY_TYPE3`}=$(if($UBXSettingsObject.VERITY_TYPE3){"Yes"}else{"No"})"
            }
            'PrcsScheduler' 
            {
                $command += "-u " +
                        "`{APPENG`}=$(if($UBXSettingsObject.APPENG){"Yes"}else{"No"})/" +
                        "`{MSTRSRV`}=$(if($UBXSettingsObject.MSTRSRV){"Yes"}else{"No"})/" +
                        "`{DOMAIN_GW`}=$(if($UBXSettingsObject.DOMAIN_GW){"Yes"}else{"No"})/" +
                        "`{VERITY_TYPE3`}=$(if($UBXSettingsObject.VERITY_TYPE3){"Yes"}else{"No"})"
            }
        }
        
        }

        # Get ready to run the command.
        Write-Verbose "Running: $PS_HOME\bin\server\WINX86\ubbgen.exe $command 2>&1"
        
        # Run the command, passing the $command as an argument to the executable.
        # The operator "2>&1" will redirect the error stream to the first stream.
        # This will pass the errors from ubbgen.exe to the variable, which can then be parsed.
        $result = cmd /c "$PS_HOME\bin\server\WINX86\ubbgen.exe $command 2>&1"

        Write-Verbose "*** Results ***"
        $result | %{ Write-Verbose $_ }
        
        return $result
    }
    End
    {
    }
}